iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0
自我挑戰組

網頁前端框架 Vue 3 從頭開始(重新挑戰)系列 第 19

vue3 Composition API 學習手冊-19 組件的綜合練習

  • 分享至 

  • xImage
  •  

Vue3 Composition API的文章寫到了Component的階段,想要來整理一下前面的進度,來製作一個綜合的案例,這個案例的規劃如下:

  1. 製作一個Fancy的下拉式選單
  2. 將這個下拉式選單製作成Vue Component
  3. 這個下拉式選單的內容(option)來自於外部(json)
  4. 下拉式選單元件的內容改變後,可以影響到非元件的內容

了解程式碼之前,可以先看看已經完成的範例檔

外部json檔

{
    "system": [
        { "id":0, "title":"請選擇手機系統", "value": "", "disabled": true, "default": true },
        { "id":1, "title":"Android", "value": "Android" },
        { "id":2, "title":"iOS", "value": "iOS" }
    ],
    "provider": [
        { "id":0, "title":"請選擇電信業者", "value": "", "disabled": true, "default": true },
        { "id":1, "title":"中華電信", "value": "CHT" },
        { "id":2, "title":"台灣大哥大", "value": "TWN" },
        { "id":3, "title":"遠傳", "value": "FET" }
    ],
}

程式碼的部分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue Component</title>
    <link href="vueComponent.css" rel="stylesheet" type="text/css">
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
    <style>
        .wrapper {
            display: flex;
            width: 700px;
            margin: auto;
        }

        .wrapper .selectDiv {
            width: 300px;
            height: 270px;
            border: black 1px solid;
            margin: 10px auto 20px auto;
        }

        .wrapper .selectDiv .icon {
            text-align: center;
        }

        .wrapper .selectDiv .icon img {
            width: 150px;
            margin-bottom: 10px;
        }
    </style>
</head>

<body>
    <div class="wrapper" id="app">
        <div class="selectDiv">
            <dropdownmenu
                :items="state.selectData.system"
                @dropdownmenu-change="state.selectedData.system = $event + '.png'">
            </dropdownmenu>
            <div class="icon">
                <img
                    v-bind:src="'images/' + state.selectedData.system"
                    v-if="state.selectedData.system !== null">
            </div>
        </div>
        <div class="selectDiv">
            <dropdownmenu
                :items="state.selectData.provider"
                @dropdownmenu-change="state.selectedData.provider = $event + '.png'">
            </dropdownmenu>
            <div class="icon">
                <img
                    v-bind:src="'images/' + state.selectedData.provider"
                    v-if="state.selectedData.provider !== null">
            </div>
        </div>
    </div>
</body>

</html>

<script>
    const { reactive, onBeforeMount } = Vue;
    const app = {
        setup(){
            const state = reactive({
                selectData: {
                    system: null,
                    provider: null,
                },
                selectedData: {
                    system: null,
                    provider: null,
                }
            })
            onBeforeMount(() => {
                axios.get("vueComponent.json").then((response) => {
                    state.selectData = response.data;
                }).catch(function (response) {
                    console.log(response);
                })
            })
            return { state }
        }
    }
    const myVue = Vue.createApp(app);
    
    myVue.component("dropdownmenu", {
        props: ['items'],
        template: `
                    <div class="section">
                        <div class="select">
                            <select :name="items" @change="dataChange">
                                <option 
                                    v-for="item in items"
                                    :value="item.value"
                                    :disabled="item.disabled"
                                    :selected="item.default"
                                    @change="dataChange">
                                    {{ item.title }}</option>
                            </select>
                        </div>
                    </div>
                `,
        setup(props, target){
            function dataChange(){
                target.emit('dropdownmenu-change', event.target.value);
            }
            return{ dataChange }
        },
    })
    myVue.mount("#app");
</script>

透過以上的程式碼來驗證我們的目標項目:

第一點. 製作一個Fancy的下拉式選單:透過CSS來建構出一個Fancy的下拉式選單
第二點. 將這個下拉式選單製作成Vue Component:透過程式碼92~115行完成,設定當使用者更換選單內容時,會發出一個dropdownmenu-change事件,並帶使用者選擇的項目value。
3. 這個下拉式選單的內容(option)來自於外部(json):透過程式碼80~86行完成,利用axios載入json檔至元件。
4. 下拉式選單元件的內容改變後,可以影響到非元件的內容:當元件發出dropdownmenu-change事件時,將值寫入vue data selectedData對應的項目中,並使用v-bind:src來綁定vue data至圖片標籤。

以上就是今天特意練習之前進度的一個範例,跟大家分享,但這樣的組件設計僅能讓該頁面使用到這個組件,如果要在多個HTML使用同一組件,我們必須先了解webpack和vue-cli的使用,接下來的文章就準備往這個方向介紹,敬請期待囉!


上一篇
vue3 Composition API 學習手冊-18 組件emit的用法
下一篇
vue3 Composition API 學習手冊-20 vue cli 環境架設
系列文
網頁前端框架 Vue 3 從頭開始(重新挑戰)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言